package cn.csc.module.distribute.service.order;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.mybatis.core.util.MyBatisUtils;
import cn.csc.module.distribute.api.downline.DistributeDownlineApi;
import cn.csc.module.distribute.api.downline.dto.DistributeDownlineDTO;
import cn.csc.module.distribute.api.order.dto.DistributeOrderDTO;
import cn.csc.module.distribute.controller.admin.order.vo.*;
import cn.csc.module.distribute.controller.app.order.vo.AppDistributeOrderAmountVO;
import cn.csc.module.distribute.controller.app.order.vo.AppDistributeOrderItemRespVO;
import cn.csc.module.distribute.controller.app.order.vo.AppDistributeOrderReqVO;
import cn.csc.module.distribute.controller.app.order.vo.AppDistributeOrderRespVO;
import cn.csc.module.distribute.convert.order.DistributeOrderConvert;
import cn.csc.module.distribute.dal.dataobject.downline.DistributeDownlineDO;
import cn.csc.module.distribute.dal.dataobject.order.DistributeOrderDO;
import cn.csc.module.distribute.dal.mysql.downline.DistributeDownlineMapper;
import cn.csc.module.distribute.dal.mysql.order.DistributeOrderMapper;
import cn.csc.module.member.api.user.MemberUserApi;
import cn.csc.module.member.api.user.dto.MemberUserRespDTO;
import cn.csc.module.order.api.item.OrderItemApi;
import cn.csc.module.order.api.item.dto.OrderItemRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static cn.csc.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.csc.module.distribute.enums.ErrorCodeConstants.DISTRIBUTE_ORDER_NOT_EXISTS;


/**
 * 分销订单记录 Service 实现类
 *
 * @author liuchuang
 */
@Slf4j
@Service
@Validated
public class DistributeOrderServiceImpl implements DistributeOrderService {

    @Resource
    private DistributeOrderMapper orderMapper;
    @Resource
    private OrderItemApi orderItemApi;
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private DistributeDownlineApi distributeDownlineApi;
    @Resource
    private DistributeDownlineMapper distributeDownlineMapper;
    @Override
    public BigInteger createOrder(DistributeOrderCreateReqVO createReqVO) {
        // 插入
        DistributeOrderDO order = DistributeOrderConvert.INSTANCE.convert(createReqVO);
        orderMapper.insert(order);
        // 返回
        return order.getId();
    }

    @Override
    public void updateOrder(DistributeOrderUpdateReqVO updateReqVO) {
        // 校验存在
        validateOrderExists(updateReqVO.getId());
        // 更新
        DistributeOrderDO updateObj = DistributeOrderConvert.INSTANCE.convert(updateReqVO);
        orderMapper.updateById(updateObj);
    }

    @Override
    public void deleteOrder(BigInteger id) {
        // 校验存在
        validateOrderExists(id);
        // 删除
        orderMapper.deleteById(id);
    }

    private void validateOrderExists(BigInteger id) {
        if (orderMapper.selectById(id) == null) {
            throw exception(DISTRIBUTE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public DistributeOrderDO getOrder(BigInteger id) {
        return orderMapper.selectById(id);
    }

    @Override
    public List<DistributeOrderDO> getOrderList(Collection<BigInteger> ids) {
        return orderMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<DistributeOrderDO> getOrderPage(DistributeOrderPageReqVO pageReqVO) {
        return orderMapper.selectPage(pageReqVO);
    }

    @Override
    public List<DistributeOrderExcelVO> getOrderExportList(DistributeOrderPageReqVO pageReqVO) {
        List<DistributeOrderExcelVO> orderList=orderMapper.selectExportList(pageReqVO);  // 分页查询符合条件的订单ID
        if (orderList!=null && orderList.size() > 0) {
            List<BigInteger> orderItemIds=orderList.stream().map(DistributeOrderExcelVO::getOrderItemId).collect(Collectors.toList());
            log.info("[DistributeOrderServiceImpl][getOrderExportList][orderItemIds]{}",orderItemIds);
            //取出子订单项
            List<OrderItemRespDTO> itemMap = orderItemApi.getByIds(orderItemIds).getCheckedData();
            log.info("[DistributeOrderServiceImpl][getOrderExportList][itemMap]{}",itemMap);
            orderList.forEach(order ->{
                Optional<OrderItemRespDTO> vo=itemMap.stream().filter(item -> item.getId().equals(order.getOrderItemId())).findFirst();
                order.setSkuName(vo.get().getSkuName());
                order.setSpuName(vo.get().getSpuName());
                order.setPrice(vo.get().getPrice());
                order.setOrderType(vo.get().getOrderType());
            });
        }
        log.info("[DistributeOrderServiceImpl][getOrderExportList][orderList]{}",orderList);
        return orderList;
    }
    @Override
    public PageResult<AppDistributeOrderRespVO> selectAdminOrderPage(DistributeOrderPageReqVO pageReqVO) {
        IPage<AppDistributeOrderRespVO> mpPage = MyBatisUtils.buildPage(pageReqVO);

        log.info("[DistributeOrderServiceImpl][selectAdminOrderPage][mpPage]{}",mpPage);
        orderMapper.selectAdminOrderPage(pageReqVO, mpPage);  // 分页查询符合条件的订单ID
        if (mpPage.getRecords().size() > 0) {
            List<BigInteger> orderIds=mpPage.getRecords().stream().map(AppDistributeOrderRespVO::getOrderId).collect(Collectors.toList());
            //取出子订单项
            Map<BigInteger, List<OrderItemRespDTO>> itemMap = orderItemApi.getByOrderIds(orderIds).getCheckedData();
            mpPage.getRecords().forEach(order ->
                    order.setOrderItems(DistributeOrderConvert.INSTANCE.convertList04(itemMap.getOrDefault(order.getOrderId(), Collections.emptyList())))
            );
            // 计算订单总金额
            // 计算佣金金额
            log.info("[DistributeOrderServiceImpl][selectAdminOrderPage][orderIds]{}",orderIds);
            List<AppDistributeOrderRespVO> amtList = selectAmountListByOrderId(pageReqVO.getOrderStatus(),orderIds);
            log.info("[DistributeOrderServiceImpl][selectAdminOrderPage][amtList]{}",amtList);
            mpPage.getRecords().forEach(order ->{
                Optional<AppDistributeOrderRespVO> vo=amtList.stream().filter(item -> item.getOrderId().equals(order.getOrderId())).findFirst();
                order.setTotalAmount(vo.get().getTotalAmount());
                order.setChildId(vo.get().getChildId());
                order.setAvatar(vo.get().getAvatar());
                order.setMemberPhone(vo.get().getMemberPhone());
                order.setParentName(vo.get().getParentName());
                order.setParentMobile(vo.get().getParentMobile());
                order.setUpdateTime(vo.get().getUpdateTime());
                order.setOrderStatus(vo.get().getOrderStatus());
                order.setPayTime(vo.get().getPayTime());
                order.setTotalCommission(vo.get().getTotalCommission());
            });
        }
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal(),  mpPage.getPages());
    }
    @Override
    public PageResult<AppDistributeOrderRespVO> selectAppOrderPage(AppDistributeOrderReqVO pageReqVO) {
        IPage<AppDistributeOrderRespVO> mpPage = MyBatisUtils.buildPage(pageReqVO);

        orderMapper.selectAppOrderPage(pageReqVO, mpPage);  // 分页查询符合条件的订单ID
        log.info("[DistributeOrderServiceImpl][selectAppOrderPage][AppDistributeOrderReqVO]{}",pageReqVO);
        if (mpPage.getRecords().size() > 0) {
            List<BigInteger> orderIds=mpPage.getRecords().stream().map(AppDistributeOrderRespVO::getOrderId).collect(Collectors.toList());
            //取出子订单项
            Map<BigInteger, List<OrderItemRespDTO>> itemMap = orderItemApi.getByOrderIds(orderIds).getCheckedData();

            mpPage.getRecords().forEach(order ->
                    order.setOrderItems(DistributeOrderConvert.INSTANCE.convertList04(itemMap.getOrDefault(order.getOrderId(), Collections.emptyList())))
            );
            // 计算订单总金额
            // 计算佣金金额
            List<AppDistributeOrderRespVO> amtList = selectAmountListByOrderId(3,orderIds);
            mpPage.getRecords().forEach(order ->{
                Optional<AppDistributeOrderRespVO> vo=amtList.stream().filter(item -> item.getOrderId().equals(order.getOrderId())).findFirst();
                order.setTotalAmount(vo.get().getTotalAmount());
                order.setAvatar(vo.get().getAvatar());
                order.setMemberPhone(vo.get().getMemberPhone());
                order.setUpdateTime(vo.get().getUpdateTime());
                order.setPayTime(vo.get().getPayTime());
                order.setTotalCommission(vo.get().getTotalCommission());
            });

        }
        log.info("[DistributeOrderServiceImpl][selectAppOrderPage][mpPage.getRecords()]{}",mpPage.getRecords());
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal(),  mpPage.getPages());
    }

    @Override
    public Map<BigInteger,List<AppDistributeOrderItemRespVO>> selectListByOrderId(List<BigInteger> orderIds) {
        List<DistributeOrderDO> orderItemList=orderMapper.selectListByOrderId(orderIds);
        List<AppDistributeOrderItemRespVO> list=DistributeOrderConvert.INSTANCE.convertList03(orderItemList);
        return list.stream()
                .collect(Collectors.groupingBy(AppDistributeOrderItemRespVO::getOrderId));
    }

    @Override
    public  List<AppDistributeOrderRespVO> selectAmountListByOrderId(Integer orderStatus,List<BigInteger> orderIds) {
        if(orderIds==null){
            return null;
        }
        Map<String,Object> param=new HashMap<>();
        param.put("orderStatus",orderStatus);
        param.put("orderIds",orderIds);
        return orderMapper.selectAmountListByOrderId(param);
    }

    @Override
    public void createOrderBatch(List<DistributeOrderDTO> createReqDto) {
        orderMapper.insertBatch( DistributeOrderConvert.INSTANCE.convertList05(createReqDto));
    }

    @Override
    public AppDistributeOrderAmountVO selectSumAmount(AppDistributeOrderReqVO reqVO) {
        List<DistributeOrderDO> orderList= orderMapper.selectOrderList(reqVO) ;
        long number=orderList.stream().map(DistributeOrderDO::getOrderId).distinct().count();

        AppDistributeOrderAmountVO resultVo= new AppDistributeOrderAmountVO();
        resultVo.setSumTotal(number);
        BigDecimal amount = orderList.stream()
                .map(dto -> dto.getAmount().multiply(new BigDecimal(dto.getCommissionRate()).divide(new BigDecimal(100))))
                .reduce(BigDecimal.ZERO, BigDecimal::add)  // 累加所有项
                .setScale(2, RoundingMode.HALF_UP);  // 最终结果保留两位小数
        resultVo.setSumCommission(amount);
        return resultVo;

    }


}
